#pragma once
#include <vector>
#include <set>
#include "System.h"
#pragma warning(disable:4251) // disable the warning: class 'std::set<_Kty>' needs to have dll-interface to be used by clients of class


class Txn;

// You could use the TxnMgr in 2 ways
// 1. Your application only has one transaction chain, just use the global default TxnMgr by TxnMgr::Get()
// 2. Your application has multiple transaction chains, such as for each document, you need to new and delete TxnMgr objects yourself.
class TXNMGR_API TxnMgr
{
public:
	TxnMgr(void);
	~TxnMgr(void);

	static TxnMgr* Get();
	static Txn* GetActiveTxn();

public:
	// Start transaction
	BOOL	StartTxn(Txn* pTxn = NULL);

	// End transaction
	BOOL	EndTxn();

	// Abort transaction
	BOOL	AbortTxn();

	// Undo transaction
	BOOL	UndoTxn();

	// Redo transaction
	BOOL	RedoTxn();

	// Truncate the undo/redo chain
	void TruncateUndoRedo();

	bool Undoable() {return m_vTxn.size() > 0;}
	bool Redoable() {return m_vTxnUndo.size() > 0;}

private:
	// Create a new transaction and add it into the list
	Txn* Add();
	// Get the active transaction
	Txn* ActiveTxn() const;

	// Get a transaction from the list upon the TxnId
	Txn* Get(int iTxnId) const;

	// Create a new transaction and add it into the list
	Txn* Add(int iTxnId);

private:
	// When we start transaction, this variable keeps the current transaction
	Txn* m_pActiveTxn;

	// The list for storing all finished transactions
	std::vector<Txn*> m_vTxn;

	// The list for storing all undone transactions
	std::vector<Txn*> m_vTxnUndo;

private:
	static std::set<TxnMgr*> m_s_TxnMgrs;
};
